

import os

from dexen.system.common.base import Individual
from dexen.system.common.meta import JobMeta
from dexen.system.common import utils
from dexen.system.server import TOP_DIR, INDS_DIR_NAME, DIR_SIZE, MASTER_DIR_NAME



class ArchiveMgr(object):
    def __init__(self, job_meta):
        assert isinstance(job_meta, JobMeta)
        self.arch_dir = os.path.join(TOP_DIR, job_meta.get_dir_name())
        self._create_dir(self.arch_dir)
        self.inds_dir = os.path.join(self.arch_dir, INDS_DIR_NAME)
        self._create_dir(self.inds_dir)
        self.master_dir = os.path.join(self.arch_dir, MASTER_DIR_NAME)
        self._create_dir(self.master_dir)
        self.job_meta = job_meta
        self._archive_schema()
    
    def _archive_schema(self):
        job_meta = self.job_meta
        assert isinstance(job_meta, JobMeta)
        ZIP_NAME = "job_def.zip"
        SCHEMA_NAME = "JobDef"
        f = open(os.path.join(self.arch_dir, ZIP_NAME), "w")
        f.write(job_meta.get_zip())
        f.close()
        utils.unzip(job_meta.get_zip(), os.path.join(self.arch_dir, SCHEMA_NAME))
    
    def _create_dir(self, path):
        if not os.path.exists(path):
            os.mkdir(path)
    
    def _get_range_str(self, id):
        base = ((id-1) / DIR_SIZE) * DIR_SIZE + 1
        ceiling = base + DIR_SIZE - 1
        return "{0:06d}_{1:06d}".format(base, ceiling)
    
    def _get_str(self, id):
        return "{0:06d}".format(id)
    
    def _write_to_file(self, archived):
        for file_name, content in archived.items():
            f = open(file_name, "w")
            f.write(content)
            f.close()
                
    def _archive_ind(self, ind):
        assert isinstance(ind, Individual)
        range_dir_name = self._get_range_str(ind.__id__)
        self._create_dir(range_dir_name)
        os.chdir(range_dir_name)
        ind_dir_name = self._get_str(ind.__id__)
        self._create_dir(ind_dir_name)
        os.chdir(ind_dir_name)
        self._write_to_file(ind._get_archived())
        ind._strip_archived() # TODO: Important
    
    def archive_inds(self, inds):
        prev_dir = os.getcwd()
        for ind in inds:
            os.chdir(self.inds_dir)
            self._archive_ind(ind)
        os.chdir(prev_dir)

    def archive_master(self, archived):
        prev_dir = os.getcwd()
        os.chdir(self.master_dir)
        self._write_to_file(archived)
        os.chdir(prev_dir)

    def delete_all(self):
        """
        The method is called, when the corresponding job is deleted by the user.
        """
        utils.rmentry(self.arch_dir)

#===============================================================================
# TESTING
#===============================================================================
def test():
    schema_meta = JobMeta(None, "HAHA")
    arc_mgr = ArchiveMgr(schema_meta)
    ind = Individual()
    ind.__id__ = 1560
    ind.archive_data("ali.txt", range(25))
    ind.archive_data("veli.txt", "Nasilsin koc hahahahahaha")
    arc_mgr.archive_data(ind)
    
    
def main():
    test()

if __name__ == "__main__":
    main()

     